﻿using System;
using ValidationHelper.Validators;

namespace ValidationHelper
{
    public class ValidationCase
    {
        #region Propriedades
        public ValidatorCollection Validators { get; private set; }
        #endregion

        #region Construtores
        public ValidationCase()
        {
            Validators = new ValidatorCollection();
        }
        #endregion

        #region Constantes
        private static readonly Type DefaultExceptionType = Type.GetType("ValidationUtils.ValidationUtilsException");
        #endregion

        #region Regular Expressions
        public const string RegexEmail = @"^(([^<>()[\]\\.,;:\s@\""]+"
                        + @"(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))@"
                        + @"((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
                        + @"\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+"
                        + @"[a-zA-Z]{2,}))$";
        public const string RegexUrl = @"^(?:http|https|ftp)://[a-zA-Z0-9\.\-]+(?:\:\d{1,5})?(?:[A-Za-z0-9\.\;\:\@\&\=\+\$\,\?/]|%u[0-9A-Fa-f]{4}|%[0-9A-Fa-f]{2})*$";
        public const string RegexIp = "";
        #endregion

        #region Métodos
        public ValidationCase AddNullValidation(object objToValidate, string exceptionMessage)
        {
            return AddNullValidation(objToValidate, exceptionMessage, DefaultExceptionType);
        }

        public ValidationCase AddNullValidation(object objToValidate, string exceptionMessage, Type exceptionType)
        {
            Validators.Add(new NullValidator(exceptionMessage, exceptionType, objToValidate));
            return this;
        }

        public ValidationCase AddNullStringValidation(string strToValidate, string exceptionMessage)
        {
            return AddNullStringValidation(strToValidate, exceptionMessage, DefaultExceptionType);
        }

        public ValidationCase AddNullStringValidation(string strToValidate, string exceptionMessage, Type exceptionType)
        {
            Validators.Add(new NullStringValidator(exceptionMessage, exceptionType, strToValidate));
            return this;
        }

        public ValidationCase AddStringMaximumLengthValidation(string strToValidate, string exceptionMessage, int maximumLength)
        {
            return AddStringMaximumLengthValidation(strToValidate, exceptionMessage, DefaultExceptionType, maximumLength);
        }

        public ValidationCase AddStringMaximumLengthValidation(string strToValidate, string exceptionMessage, Type exceptionType, int maximumLength)
        {
            Validators.Add(new StringMaximumLengthValidator(exceptionMessage, exceptionType, strToValidate, maximumLength));
            return this;
        }

        public ValidationCase AddStringMinimumLengthValidation(string strToValidate, string exceptionMessage, int minimumLength)
        {
            return AddStringMinimumLengthValidation(strToValidate, exceptionMessage, DefaultExceptionType, minimumLength);
        }

        public ValidationCase AddStringMinimumLengthValidation(string strToValidate, string exceptionMessage, Type exceptionType, int minimumLength)
        {
            Validators.Add(new StringMinimumLengthValidator(exceptionMessage, exceptionType, strToValidate, minimumLength));
            return this;
        }

        public ValidationCase AddStringRangeLengthValidation(string strToValidate, string exceptionMessage, int minimumLength, int maximumLength)
        {
            return AddStringRangeLengthValidation(strToValidate, exceptionMessage, DefaultExceptionType, minimumLength, maximumLength);
        }

        public ValidationCase AddStringRangeLengthValidation(string strToValidate, string exceptionMessage, Type exceptionType, int minimumLength, int maximumLength)
        {
            Validators.Add(new StringRangeLengthValidator(exceptionMessage, exceptionType, strToValidate, minimumLength, maximumLength));
            return this;
        }

        public ValidationCase AddCpfValidation(string cpf, string exceptionMessage)
        {
            return AddCpfValidation(cpf, exceptionMessage, DefaultExceptionType);
        }

        public ValidationCase AddCpfValidation(string cpf, string exceptionMessage, Type exceptionType)
        {
            throw new NotImplementedException();
        }

        public ValidationCase AddCnpjValidation(string cnpj, string exceptionMessage)
        {
            return AddCnpjValidation(cnpj, exceptionMessage, DefaultExceptionType);
        }

        public ValidationCase AddCnpjValidation(string cnpj, string exceptionMessage, Type exceptionType)
        {
            throw new NotImplementedException();
        }

        public ValidationCase AddRegexValidation(string strToValidate, string exceptionMessage, string regularExpression)
        {
            return AddRegexValidation(strToValidate, exceptionMessage, DefaultExceptionType, regularExpression);
        }

        public ValidationCase AddRegexValidation(string strToValidate, string exceptionMessage, Type exceptionType, string regularExpression)
        {
            Validators.Add(new RegexValidator(exceptionMessage, exceptionType, strToValidate, regularExpression));
            return this;
        }

        public ValidationCase AddCompareValidation(double numberToValidate, string exceptionMessage, double numberToCompare, CompareType compareType)
        {
            return AddCompareValidation(numberToValidate, exceptionMessage, DefaultExceptionType, numberToCompare, compareType);
        }

        public ValidationCase AddCompareValidation(double numberToValidate, string exceptionMessage, Type exceptionType, double numberToCompare, CompareType compareType)
        {
            Validators.Add(new CompareValidator(exceptionMessage, exceptionType, numberToValidate, numberToCompare, compareType));
            return this;
        }

        public ValidationCase AddCompareReferenceValidation(object objToValidate, string exceptionMessage, object objToCompare)
        {
            return AddCompareReferenceValidation(objToValidate, exceptionMessage, DefaultExceptionType, objToCompare);
        }

        public ValidationCase AddCompareReferenceValidation(object objToValidate, string exceptionMessage, Type exceptionType, object objToCompare)
        {
            throw new NotImplementedException();
        }

        public ValidationCase AddRangeValidation(double value, string exceptionMessage, double initialValue, double finalValue, bool includeLimits)
        {
            return AddRangeValidation(value, exceptionMessage, DefaultExceptionType, initialValue, finalValue, includeLimits);
        }

        public ValidationCase AddRangeValidation(double value, string exceptionMessage, Type exceptionType, double initialValue, double finalValue, bool includeLimits)
        {
            Validators.Add(new RangeValidator(exceptionMessage, exceptionType, value, initialValue, finalValue, includeLimits));
            return this;
        }

        public ValidationCase AddDateRangeValidation(DateTime date, string exceptionMessage, DateTime initialDate, DateTime finalDate, bool includeLimits)
        {
            return AddDateRangeValidation(date, exceptionMessage, DefaultExceptionType, initialDate, finalDate, includeLimits);
        }

        public ValidationCase AddDateRangeValidation(DateTime date, string exceptionMessage, Type exceptionType, DateTime initialDate, DateTime finalDate, bool includeLimits)
        {
            throw new NotImplementedException();
        }

        public ValidationCase AddEnumValidation(string enumeration, string exceptionMessage, Type enumType)
        {
            return AddEnumValidation(enumeration, exceptionMessage, DefaultExceptionType, enumType);
        }

        public ValidationCase AddEnumValidation(string enumeration, string exceptionMessage, Type exceptionType, Type enumType)
        {
            throw new NotImplementedException();
        }

        public void Validate()
        {
            foreach (Validator v in Validators)
            {
                v.Validate();
            }
        }
        #endregion
    }
}